﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;



using DatabaseCompare.Model;
using DatabaseCompare.Service.Reader;
using DatabaseCompare.Service.Compare;
using DatabaseCompare.ServiceImpl.Reader;
using DatabaseCompare.ServiceImpl.Compare;

using DatabaseCompare.Config;


namespace DatabaseCompare.App
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }





        /// <summary>
        /// SQL Server 2005 读取器.
        /// </summary>
        private IDatabaseInfoReader reader = new Sql2005DatabaseInfoReader();


        /// <summary>
        /// 数据库比较类.
        /// </summary>
        DatabaseCompare.ServiceImpl.Compare.DatabaseCompare databaseCompare = new DatabaseCompare.ServiceImpl.Compare.DatabaseCompare();


        /// <summary>
        /// 左数据库.
        /// </summary>
        private DatabaseInfo leftDatabaseInfo;

        /// <summary>
        /// 右数据库.
        /// </summary>
        private DatabaseInfo rightDatabaseInfo;


        /// <summary>
        /// 比较结果.
        /// </summary>
        private DatabaseCompareResult compareResult;


        /// <summary>
        /// 用于显示的比较结果列表.
        /// </summary>
        private List<ICompareAbleResult> displayResultList = new List<ICompareAbleResult>();


        /// <summary>
        /// 数据库配置.
        /// </summary>
        private ConfigManager configManager = ConfigManager.GetInstance();




        #region 事件


        /// <summary>
        /// 初始化.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormMain_Load(object sender, EventArgs e)
        {
            // 初始化 左数据库显示.
            InitTlvLeft();
            // 初始化 右数据库显示.
            InitTlvRight();
            // 初始化 比较结果列表显示.
            InitTlvResult();

            // 读取数据库配置.
            configManager.ReadConfig();
            // 初始化连接字符串.
            InitConnString();
        }


        /// <summary>
        /// 配置菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void configToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }


        /// <summary>
        /// 退出菜单.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }



        /// <summary>
        /// 取得数据库的显示列表.
        /// </summary>
        /// <param name="dbInfo"></param>
        /// <returns></returns>
        private List<CompareAble> GetDisplayData(DatabaseInfo dbInfo)
        {
            // 准备用于显示的列表.
            List<CompareAble> displayList = new List<CompareAble>();

            // 加入表数据.
            foreach (CompareAble data in dbInfo.TableList)
            {
                displayList.Add(data);
            }

            // 加入视图数据.
            foreach (CompareAble data in dbInfo.ViewList)
            {
                displayList.Add(data);
            }

            // 加入 触发器.
            foreach (CompareAble data in dbInfo.TriggerList)
            {
                displayList.Add(data);
            }

            // 加入 存储过程.
            foreach (CompareAble data in dbInfo.ProcedureList)
            {
                displayList.Add(data);
            }

            // 加入 函数
            foreach (CompareAble data in dbInfo.FunctionList)
            {
                displayList.Add(data);
            }

            return displayList;
        }


        /// <summary>
        /// 读取左数据库.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReadLeft_Click(object sender, EventArgs e)
        {
            reader.DatabaseName = lblDB1.Text;
            reader.ConnectString = configManager.DatabaseConfig[cboConnLeft.SelectedIndex].ConnectString;
            leftDatabaseInfo = reader.ReadDatabaseInfo();

            tlvLeft.Objects = GetDisplayData(leftDatabaseInfo);
        }


        /// <summary>
        /// 读取右数据库
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReadRight_Click(object sender, EventArgs e)
        {
            reader.DatabaseName = lblDB2.Text;
            reader.ConnectString = configManager.DatabaseConfig[cboConnRight.SelectedIndex].ConnectString;
            rightDatabaseInfo = reader.ReadDatabaseInfo();

            tlvRight.Objects = GetDisplayData(rightDatabaseInfo);
        }



        /// <summary>
        /// 比较.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCompare_Click(object sender, EventArgs e)
        {
            // 比较处理.
            compareResult = databaseCompare.Compare(leftDatabaseInfo, rightDatabaseInfo);

            // 清除结果.
            displayResultList.Clear();

            // 隐藏相同标志设置为 False.
            chkHideSame.Checked = false;

            // 加入表结果.
            foreach (TableCompareResult data in compareResult.TableCompareResultList)
            {
                displayResultList.Add(data);
            }

            // 加入视图结果.
            foreach (ViewCompareResult data in compareResult.ViewCompareResultList)
            {
                displayResultList.Add(data);
            }

            // 加入触发器结果.
            foreach (TriggerCompareResult data in compareResult.TriggerCompareResultList)
            {
                displayResultList.Add(data);
            }

            // 加入存储过程结果.
            foreach (ProcedureCompareResult data in compareResult.ProcedureCompareResultList)
            {
                displayResultList.Add(data);
            }

            // 加入函数结果.
            foreach (FunctionCompareResult data in compareResult.FunctionCompareResultList)
            {
                displayResultList.Add(data);
            }


            tlvResult.Objects = displayResultList;
        }



        /// <summary>
        /// 隐藏相同.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chkHideSame_CheckedChanged(object sender, EventArgs e)
        {

            if (chkHideSame.Checked)
            {
                // 排除完全匹配的.
                var query =
                    from data in displayResultList
                    where data.CompareResult != CommonCompareResult.FullSame
                    select data;

                tlvResult.Objects = query.ToList();
            }
            else
            {
                // 全部显示.
                tlvResult.Objects = displayResultList;
            }
        }




        #endregion 事件





        /// <summary>
        /// 初始化连接字符串.
        /// </summary>
        private void InitConnString()
        {
            foreach(DbConfig config in configManager.DatabaseConfig) {
                cboConnLeft.Items.Add(config.DatabaseName);
                cboConnRight.Items.Add(config.DatabaseName);
            }

            cboConnLeft.SelectedIndex = 0;
            cboConnRight.SelectedIndex = 0;
        }









        #region 数据库下树型列表如何显示.

        /// <summary>
        /// 树形列表委托.
        /// 当前节点下面，是否有子节点.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        private bool InfoCanExpandGetter(object x)
        {
            if (x is CompareAbleWithSubList<ColumnInfo>)
            {
                // 如果是包含 列的列表的，可以展开.
                return true;
            }

            // 其他的不能展开.
            return false;
        }



        /// <summary>
        /// 树形列表委托.
        /// 点击父亲节点之后，如何显示子节点.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        private System.Collections.IEnumerable InfoChildrenGetter(object x)
        {
            if (x is CompareAbleWithSubList<ColumnInfo>)
            {
                // 如果是包含 列的列表的，展开列表数据.
                return ((CompareAbleWithSubList<ColumnInfo>)x).SubList;
            }

            // 其他的不能展开.
            return null;
        }


        /// <summary>
        /// 名称如何显示.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        private Object NameAspectGetter(object x)
        {
            if (x is CompareAble)
            {
                // 如果是 可比较的，返回名称.
                return ((CompareAble)x).Name;
            }

            // 其他的不能展开.
            return String.Empty;
        }

        /// <summary>
        /// 备注如何显示.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        private Object CommentAspectGetter(object x)
        {
            if (x is CompareAble)
            {
                // 如果是 可比较的，返回备注.
                return ((CompareAble)x).Comment;
            }

            // 其他的不能展开.
            return String.Empty;
        }


        /// <summary>
        /// 取得图片索引.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        private Object ImageGetter(object x)
        {
            if (x is TableInfo)
            {
                // 表
                return "table.ico";
            }
            else if (x is ViewInfo)
            {
                // 视图
                return "view.ico";
            }
            else if (x is ColumnInfo)
            {
                // 列
                return "column.ico";
            }
            else if (x is TriggerInfo)
            {
                // 触发器.
                return "trigger.ico";
            }
            else if (x is ProcedureInfo)
            {
                // 存储过程.
                return "procedure.ico";
            }
            else if (x is FunctionInfo)
            {
                // 函数
                return "function.ico";
            }

            // 其他的无图片.
            return -1;
        }



        /// <summary>
        /// 初始化 左数据库显示.
        /// </summary>
        private void InitTlvLeft()
        {
            // 节点是否有子节点.
            tlvLeft.CanExpandGetter = new BrightIdeasSoftware.TreeListView.CanExpandGetterDelegate(this.InfoCanExpandGetter);

            // 如何获取自节点数据.
            tlvLeft.ChildrenGetter = new BrightIdeasSoftware.TreeListView.ChildrenGetterDelegate(this.InfoChildrenGetter);

            // 名称的显示.
            olvLeftName.AspectGetter = new BrightIdeasSoftware.AspectGetterDelegate(this.NameAspectGetter);

            // 备注的显示.
            olvLeftComment.AspectGetter = new BrightIdeasSoftware.AspectGetterDelegate(this.CommentAspectGetter);

            // 图标的显示.
            olvLeftName.ImageGetter = new BrightIdeasSoftware.ImageGetterDelegate(this.ImageGetter);
        }


        /// <summary>
        /// 初始化 右数据库显示.
        /// </summary>
        private void InitTlvRight()
        {
            // 节点是否有子节点.
            tlvRight.CanExpandGetter = new BrightIdeasSoftware.TreeListView.CanExpandGetterDelegate(this.InfoCanExpandGetter);

            // 如何获取自节点数据.
            tlvRight.ChildrenGetter = new BrightIdeasSoftware.TreeListView.ChildrenGetterDelegate(this.InfoChildrenGetter);

            // 名称的显示.
            olvRightName.AspectGetter = new BrightIdeasSoftware.AspectGetterDelegate(this.NameAspectGetter);

            // 备注的显示.
            olvRightComment.AspectGetter = new BrightIdeasSoftware.AspectGetterDelegate(this.CommentAspectGetter);

            // 图标的显示.
            olvRightName.ImageGetter = new BrightIdeasSoftware.ImageGetterDelegate(this.ImageGetter);
        }

        #endregion





        #region 比较结果列表如何显示.


        /// <summary>
        /// 备注如何显示.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        private Object ResultNameAspectGetter(object x, bool isLeft)
        {
            CompareAble compareInfo = null;
            if (x is TableCompareResult)
            {
                // 表
                compareInfo = isLeft ? ((TableCompareResult)x).Left : ((TableCompareResult)x).Right;
            }
            else if (x is ViewCompareResult)
            {
                // 视图
                compareInfo = isLeft ? ((ViewCompareResult)x).Left : ((ViewCompareResult)x).Right;
            }
            else if (x is ColumnCompareResult)
            {
                // 列
                compareInfo = isLeft ? ((ColumnCompareResult)x).Left : ((ColumnCompareResult)x).Right;
            }
            else if (x is TriggerCompareResult)
            {
                // 触发器
                compareInfo = isLeft ? ((TriggerCompareResult)x).Left : ((TriggerCompareResult)x).Right;
            }
            else if (x is ProcedureCompareResult)
            {
                // 存储过程
                compareInfo = isLeft ? ((ProcedureCompareResult)x).Left : ((ProcedureCompareResult)x).Right;
            }
            else if (x is FunctionCompareResult)
            {
                // 函数
                compareInfo = isLeft ? ((FunctionCompareResult)x).Left : ((FunctionCompareResult)x).Right;
            }

            if (compareInfo != null)
            {
                return compareInfo.Name;
            }

            return String.Empty;
        }



        /// <summary>
        /// 初始化结果列表.
        /// </summary>
        private void InitTlvResult()
        {
            // 节点是否有子节点.
            tlvResult.CanExpandGetter = delegate(object x)
            {
                if (x is TableCompareResult)
                {
                    TableCompareResult tResult = x as TableCompareResult;

                    if (tResult.ColumnCompareResultList != null)
                    {
                        // 表可以展开
                        return true;
                    }
                }
                else if (x is ViewCompareResult)
                {
                    ViewCompareResult vReult = x as ViewCompareResult;

                    if (vReult.ColumnCompareResultList != null)
                    {
                        // 视图可以展开
                        return true;
                    }
                }
                return false;
            };


            // 如何获取自节点数据.
            tlvResult.ChildrenGetter = delegate(object x)
            {
                //if (!chkHideSame.Checked)
                //{
                    // 全部显示.
                    if (x is TableCompareResult)
                    {
                        // 表下面的列
                        return ((TableCompareResult)x).ColumnCompareResultList;
                    }
                    else if (x is ViewCompareResult)
                    {
                        // 视图下面的列
                        return ((ViewCompareResult)x).ColumnCompareResultList;
                    }
                //}
                //else
                //{
                //    // 隐藏相同的.
                //    if (x is TableCompareResult)
                //    {
                //        // 表下面的列
                //        return ((TableCompareResult)x).ColumnCompareResultList.FindAll(p=>p.CompareResult != CommonCompareResult.FullSame);
                //    }
                //    else if (x is ViewCompareResult)
                //    {
                //        // 视图下面的列
                //        return ((ViewCompareResult)x).ColumnCompareResultList.FindAll(p => p.CompareResult != CommonCompareResult.FullSame);
                //    }
                //}
                return null;
            };


            olvColType.ImageGetter = delegate(object x)
            {
                if (x is TableCompareResult)
                {
                    // 表
                    return "table.ico";
                }
                else if (x is ViewCompareResult)
                {
                    // 视图
                    return "view.ico";
                }
                else if (x is ColumnCompareResult)
                {
                    // 列
                    return "column.ico";
                }
                else if (x is TriggerCompareResult)
                {
                    // 触发器
                    return "trigger.ico";
                }
                else if (x is ProcedureCompareResult)
                {
                    // 存储过程
                    return "procedure.ico";
                }
                else if (x is FunctionCompareResult)
                {
                    // 函数
                    return "function.ico";
                }

                return -1;
            };




            // 类型如何显示
            olvColType.AspectGetter = delegate(object x)
            {
                if (x is TableCompareResult)
                {
                    // 表
                    return "表";
                }
                else if (x is ViewCompareResult)
                {
                    // 视图
                    return "视图";
                }
                else if (x is ColumnCompareResult)
                {
                    // 列
                    return "列";
                }
                else if (x is TriggerCompareResult)
                {
                    // 触发器
                    return "触发器";
                }
                else if (x is ProcedureCompareResult)
                {
                    // 存储过程
                    return "存储过程";
                }
                else if (x is FunctionCompareResult)
                {
                    // 函数
                    return "函数";
                }                

                return String.Empty;
            };




            // 左名字如何显示.
            olvColResultNameLeft.AspectGetter = delegate(object x)
            {
                return ResultNameAspectGetter(x, true);
            };

            // 右名字如何显示.
            olvColResultNameRight.AspectGetter = delegate(object x)
            {
                return ResultNameAspectGetter(x, false);
            };


            // 比较结果如何显示.
            olvColResultCompare.AspectGetter = delegate(object x)
            {
                return x.ToString();
            };

        }



        #endregion 比较结果列表如何显示.







    }
}
